import java.io.* ;
import java.net.* ;
import java.util.* ;

public class MyTftpClient {
	
	public static final int BLOCKSIZE = 512;
	
	public static void main(String[] args ) throws Exception {
		
		if( args.length != 2 ) {
			System.out.printf("usage: java EchoClient maquina_do_servidor porto\n") ;
			System.exit(0);
		}

		// Criar um scanner auxiliar para ler linhas completas do canal de entrada standard.
		Scanner in = new Scanner( System.in ) ;
		
		// Preparar endereco e o porto do servidor
		String servidor = args[0] ;
		int port = Integer.parseInt( args[1] ) ;
		InetAddress serverAddress = InetAddress.getByName( servidor ) ;
		
		// Preparar o socket para trocar mensagens (datagramas)
		DatagramSocket socket = new DatagramSocket() ;
		
		// Ler o pedido do canal "standard input".

		String request = in.nextLine();
		byte[] requestData = request.getBytes() ;
		
		// Criar a mensagem para enviar
		/**tftp request packet
 *         2 bytes   string   1 byte  string   1 byte   optional options (strings)
 *         -----------------------------------------+ - - - + - + - - - + - + ->
 *RRQ/WRQ | 01/02 | Filename |  0  |   Mode   |  0  |  opt1 | 0 | value1| 0 | ...
 *         -----------------------------------------+ - - - + - + - - - + - + ->
 *	Modes (ascii chars/1 byte each):
 *		"netascii", "octet",...
 **/
		//DatagramPacket readRequest = new DatagramPacket( requestData, requestData.length ) ;
		DatagramPacket readRequest = new DatagramPacket( new byte[BLOCKSIZE+4], BLOCKSIZE+4);
		TftpPacket reqpkt = new TftpPacket( readRequest.getData(), readRequest.getLength());
		reqpkt.setOpcode( TftpPacket.RRQ );
		reqpkt.setFilename(request, "octet");
		
		//DatagramPacket readRequest = new DatagramPacket( requestData, requestData.length ) ;
		
		readRequest.setAddress( serverAddress ) ;
		readRequest.setPort( port ) ;

		socket.send( readRequest) ;
		
		// Criar uma mensagem vazia para receber a resposta 
		byte[] buffer = new byte[65536] ;

		DatagramPacket reply = new DatagramPacket( buffer, buffer.length ) ;

		//boolean fim = false;
		FileOutputStream s = new FileOutputStream(request);
		
		for(int i=0; i<reqpkt.getBlockCount(); i++){
			socket.receive(reply) ;
			
			TftpPacket rep = new TftpPacket( reply.getData(), reply.getLength());
			if(rep.getOpcode()==TftpPacket.DATA){
				//ack
				DatagramPacket ackD = new DatagramPacket(new byte[1024], 1024) ;
				TftpPacket ack=new TftpPacket(ackD.getData(),ackD.getLength());
				ack.setOpcode(TftpPacket.ACK);
				socket.send(ackD);
				
				s.write(reply.getData());
				s.close();
				socket.close();	
			}
		}
		
		/*while(!fim){
			if(reply.getLength()<BLOCKSIZE){
				
				socket.receive(reply) ;
				
				TftpPacket rep = new TftpPacket( reply.getData(), reply.getLength());
				if(rep.getOpcode()==TftpPacket.DATA){
					//ack
					DatagramPacket ackD = new DatagramPacket(null, 0) ;
					TftpPacket ack=new TftpPacket(ackD.getData(),ackD.getLength());
					ack.setOpcode(TftpPacket.ACK);
					socket.send(ackD);
					
					s.write(reply.getData());
					s.close();
					socket.close();	
				fim = true;
				}
			}else{
				TftpPacket rep = new TftpPacket( reply.getData(), reply.getLength());
				if(rep.getOpcode()==TftpPacket.DATA){
					//ack
					DatagramPacket ackD = new DatagramPacket( null, 0 ) ;
					TftpPacket ack=new TftpPacket(ackD.getData(),ackD.getLength());
					ack.setOpcode(TftpPacket.ACK);
					socket.send(ackD);
					
					socket.receive( reply ) ;
					s.write(reply.getData());
				}
			}
		}*/
		
		// Constroi uma string com o conteudo da mensagem
		//String echoedMsg = new String( echoReply.getData(), 0, echoReply.getLength() ) ;
		//System.out.printf("A resposta foi: \"%s\"\n", echoedMsg ) ;
	}	

}